﻿package gui.hug;

import flash.events.Event;
import flash.events.MouseEvent;

class HUGPagination extends HUGSprite {	
	
	public static inline var BASE : UInt = 0;
    public static inline var RECT_AS_SEL : UInt = 1;
    public static inline var RIGHT_ALIGNED : UInt = 2;
	public static inline var RECT_AS_SEL_RIGHT_ALIGNED : UInt = 3;
    
    private static inline var SEL_LINE_COL : UInt = 0x45668e;
    private static inline var SEL_RECT_COL : UInt = 0xeef2f4;
    private static inline var DX1 : UInt = 2; // distance between buttons
    private static inline var DX2 : UInt = 5; // distance between buttons
    
    private var elemsOnPage : UInt; // elements count on a page
    
    private var p_cnt : UInt; // pages count
    private var cur_p : Int; // current page
    private var tp : UInt; // pagination type
    private var p_vis : UInt; // visible pages count = 2 * p_vis + 1
    private var y2 : Float;
    private var cur_x : Float;
    
    private var cont1 : HUGSprite; // up buttons container
    private var cont2 : HUGSprite; // down buttons container
    private var cp1 : HUGSprite; // "current page" up sprite
    private var cp2 : HUGSprite; // "current page" down sprite
    
    public function new(totalCount : UInt, x : UInt, y : UInt, height : UInt = 0, type : UInt = 0, pagesVisible : UInt = 2, elemsOnPage : UInt = 10) 
    {
		var button :  HUGCheckBox = new HUGCheckBox("My Check Box", 200, 450); 
		this.addChild(button);
		
		this.cur_x = 0;
		this.cur_p = 0;
		this.y2 = 0;
      this.x = x;
      this.y = y;
      this.elemsOnPage = elemsOnPage;
      tp = type;
      p_vis = pagesVisible;
      p_cnt = Math.ceil(totalCount / elemsOnPage);
      this.height = height;
	  super();
      
	  cont1 = new HUGSprite();
      cont2 = new HUGSprite();
	  
      addChild(cont1);
      addChild(cont2);

      createCp();
      update();
    }
    
    public function getHeight() : Float
    {
      return cont2.y;
    }
    
    public function setHeight(val : Float) 
    {
      y2 = Math.max(val, 20);
      cont2.y = y2;
    }
    
    public function getCurPage() : UInt
    {
      return cur_p;
    }
    
    public function setCurPage(val : UInt) 
    {
      cur_p = val;
      update();
    }
    
    public function getNumPages() : UInt
    {
      return p_cnt;
    }
    
    // -------------------------------------------------------------------- Private methods
    private function createCp()  // Create "current page" sprites
    {
      cp1 = new HUGSprite();
      cp2 = new HUGSprite();
      
      cp2.y = -2;
      
      if (tp == RECT_AS_SEL || tp == RECT_AS_SEL_RIGHT_ALIGNED)
      {
        Utils.rect(cp1, 0, 0, 40, 20, SEL_RECT_COL, Utils.BLUE_BK_COL);
        Utils.rect(cp2, 0, 0, 40, 20, SEL_RECT_COL, Utils.BLUE_BK_COL);
        
        cp1.y = -2;
      } else {
        Utils.fillRect(cp1, 0, 0, 10, 2, SEL_LINE_COL);
        Utils.fillRect(cp2, 0, 0, 10, 2, SEL_LINE_COL);
        
        cp1.y = 16;
      }
      
      cp1.visible = false;
      cp2.visible = false;
      
      cont1.addChild(cp1);
      cont2.addChild(cp2);
    }
    
    private function updCp(xx : Float, w : Float)  // update "current page" sprites
    {
      if (tp == RECT_AS_SEL || tp == RECT_AS_SEL_RIGHT_ALIGNED)
      {
        cp1.x = cp2.x = xx - 3;
        cp1.width = cp2.width = w + ((cur_p == 7 || cur_p == 8) ? 4  :  5);
      } else {
        cp1.x = cp2.x = xx;
        cp1.width = cp2.width = w + 2;
      }
    }
    
    private function addBut(s : String, up : Bool, cur : Bool) : Float
    {
      var bt = (tp == RECT_AS_SEL || tp == RECT_AS_SEL_RIGHT_ALIGNED)
        ? new LinkButton(s, cur_x, 0) 
		:  new LightButton(s, cur_x, 0, 0, -1, 0x45668e, Utils.BUT1_TXT_COL, 0xffffff, LightButton.CENTER, 11, 1);

      if (cur) {
        if (tp != RECT_AS_SEL && tp != RECT_AS_SEL_RIGHT_ALIGNED) {
			bt.setBold(true);
		}
        updCp(bt.x, bt.width);
        bt.enabled = false;
      } else {
		  bt.addEventListener(MouseEvent.CLICK, onBut);
	  }

      if (up)
        cont1.addChild(bt);
      else
        cont2.addChild(bt);

      return bt.width + ((tp == RECT_AS_SEL || tp == RECT_AS_SEL_RIGHT_ALIGNED) ? DX2  :  DX1);
    }
    
    private function addButs(s : String, cur : Bool = false) 
    {
      addBut(s, true, cur);
      var dx : Float = addBut(s, false, cur);
      
      cur_x += dx;
    }
    
    private function update() 
    {
      clearLayout(cont1);
      clearLayout(cont2);

      if (p_cnt <= 1) {
        cp1.visible = false;
        cp2.visible = false;
        return;
      }

      cp1.visible = true;
      cp2.visible = true;

      cur_x = (cur_p == 0  &&  (tp == RIGHT_ALIGNED || tp == RECT_AS_SEL_RIGHT_ALIGNED)) ? 3  :  0;

      // create page buttons
      var i : Int;
      if (p_cnt <= p_vis * 2 + 1)
      {
        for (i in 0...p_cnt)
        {
          addButs("" + (i + 1), (i == cur_p));
        }
      } else
      {
        var p1 : Int = Math.round(Math.max(0, cur_p - p_vis));
        var p2 : Int = Math.round(Math.min(p_cnt - 1, cur_p + p_vis));
        
        if (p1 > 0)
          addButs("«");

        for (i in p1...(p2 + 1))
        {
          addButs("" + (i + 1), (i == cur_p));
        }

        if (p2 < p_cnt - 1)
          addButs("»");
      }
      
      if (tp == RIGHT_ALIGNED || tp == RECT_AS_SEL_RIGHT_ALIGNED) {
        cont1.x = cont2.x = -cont1.width + ((cur_p == p_cnt - 1) ? 1  :  0);
      }
    }
    
    // -------------------------------------------------------------------- Event handlers
    private function onBut(e : MouseEvent) 
    {
      var idx : Int = e.target.IntVal;
      if (idx < 0)
        idx = p_cnt - 1;
      else
        idx --;
      
      setCurPage(idx);
      dispatchEvent(new Event(Event.CHANGE));
    }
    
    // -------------------------------------------------------------------- Static methods
    private static function clearLayout(obj : HUGSprite) 
    {
      while (obj.numChildren > 1) // first element is the "current page" sprite
        obj.removeChildAt(obj.numChildren - 1);
    }
}